const LOOKUP_SERVICE_HOST = 'lookup-service.whitehatgaming.com'; $(document).ready(function () { /** In order to override the below Cookie Banner html, please define `window.cookieNoticeHtml` on specific site. @note Don't forget to add `id="CookieNoticeContainer"` to principal div, also `cookieNoticeGrantConsent()` and` closeCookieNoticePopup()` on buttons clicks. @example // on jsutils.php or any js file window.cookieNoticeHtml = `
`; */ var cookieNoticeHtml = window.cookieNoticeHtml || ` `; $('body').append(cookieNoticeHtml); }); $(document).ready(function () { $('body').on('click', '#register, #signup a, button#register, a[href="/?modal_reg"], [data-action="reg-show"]', function (e) { e.preventDefault(); e.stopImmediatePropagation(); window.location.href = '/create-account'; }); }); const GAMES_API = "https:\/\/game-service.whitehatgaming.com\/api"; const ENABLE_SCROLL_TOP_AFTER_WITHDRAW = true; const USER_FLAG_TEST_GAMES = false; setCookie('tzo',- new Date().getTimezoneOffset(),1) var hostname = 'www.hellocasino.com'; var is_mobile = 0; var isLoggedIn = false; var pageInitialized = false; var ip_trusted = 0; var missingMarketingPrefs = false; /** * Validator and brute-force checksum generator for "Clave Bancaria Uniforme" * fromat used in the Argentinan banking system. * * Legal stuff at http://www.infoleg.gob.ar/infolegInternet/anexos/45000-49999/47564/norma.htm * Code based on https://gist.github.com/delucas/4526176 * Universal loader based on https://gist.github.com/jrburke/1262861 */ /* global define, window */ (function (define) { var cbuValidator = {}; // Validation error codes cbuValidator.errorCode = { "OK": 0, "BAD_LENGTH": 1, "BAD_BANKBRANCH": 2, "BAD_ACCOUNT": 3 }; // Validate CBU code length cbuValidator.validateCBULength = function (cbu) { return cbu.length === 22; }; // Validate the bank/branch section of a CBU cbuValidator.validateBankBranch = function (code) { if (code.length != 8) { return false; } var bank = code.substr(0, 3), checksum1 = code[3], branch = code.substr(4, 3), checksum2 = code[7], sum = bank[0] * 7 + bank[1] * 1 + bank[2] * 3 + checksum1 * 9 + branch[0] * 7 + branch[1] * 1 + branch[2] * 3, diff = 10 - (sum % 10); return diff == checksum2; }; // Validate the account section of a CBU cbuValidator.validateAccount = function (num) { if (num.length != 14) { return false; } var checksum = num[13], sum = num[0] * 3 + num[1] * 9 + num[2] * 7 + num[3] * 1 + num[4] * 3 + num[5] * 9 + num[6] * 7 + num[7] * 1 + num[8] * 3 + num[9] * 9 + num[10] * 7 + num[11] * 1 + num[12] * 3, diff = 10 - (sum % 10); return diff == checksum; }; // Validate a CBU code cbuValidator.validateCBU = function (cbu) { if (cbuValidator.validateCBULength(cbu)) { if (cbuValidator.validateBankBranch(cbu.substr(0, 8))) { if (cbuValidator.validateAccount(cbu.substr(8, 14))) { return cbuValidator.errorCode.OK; } else { return cbuValidator.errorCode.BAD_ACCOUNT; } } else { return cbuValidator.errorCode.BAD_BANKBRANCH; } } else { return cbuValidator.errorCode.BAD_LENGTH; } }; // Tiny brute force bank + branch + checksums generator cbuValidator.getBankBranchCode = function (bank, branch) { if (bank.length !== 3 || branch.length !== 3) { return null; } for (var ck1 = 0; ck1 < 10; ck1++) { for (var ck2 = 0; ck2 < 10; ck2++) { var code = bank + ck1 + branch + ck2; if (cbuValidator.validateBankBranch(code)) { return code; } } } }; // Tiny brute force account + checksum generator cbuValidator.getAccountCode = function (account) { if (account.length !== 13) { return null; } for (var ck = 0; ck < 10; ck++) { var code = account + ck; if (cbuValidator.validateAccount(code)) { return code; } } }; // expose module interface define("cbuValidator", function () { return cbuValidator; }); })(typeof define === "function" && define.amd ? define : function (id, factory) { if (typeof module !== "undefined" && module.exports) { // Node.js module.exports = factory(); } else { // Create a global function window[id] = factory(); } }); var reason = 'increase'; var actionid; $(document).ready(function() { var sga = $('#deposit-limit-sga-period-info').length; if(sga){ if($("#period").length && ($('#period option:selected').val() == "" || $('#value').val() == "")){ toggleSubmit(false, '#generic-submit'); } $(".deposit-limit-calc").change(function() { processSGADepositLimitSelections(); }); $(".sga-answer").click(function () { var period = $('#period option:selected').val(); var value = $('#value').val(); if($(this).data("id")){ recordDOCAudit(actionid, 'sga-doc-disagree', 'Disagreed for limit of '+value+' '+period+' - change disallowed'); $("#editlimits").hide(); $("#deposit-limit-sga-rg-"+reason).show(); $("#deposit-limit-intro").hide(); $("#deposit-limit-sga-period-info").hide(); document.body.scrollTop = document.documentElement.scrollTop = 0; } else{ recordDOCAudit(actionid, 'sga-doc-agree', 'Agreed for limit of '+value+' '+period+' - change allowed'); //Submit form with tmp button in order to check password (required) is filled where required. var form = document.querySelector('#editlimits') var tmpSubmit = document.createElement('button') //If form is valid then hide the divs. if(form.checkValidity()){ $("#deposit-limit-sga-period-info").hide(); $("#deposit-limit-sga-duty-of-care").hide(); //Show submit again, incase password fails. $("#deposit-limit-submit").show(); toggleSubmit(true, '#generic-submit'); } form.appendChild(tmpSubmit) tmpSubmit.click() form.removeChild(tmpSubmit) } }); $(".sga-select-limit-again").click(function () { $("#deposit-limit-sga-rg-init10k").hide(); $("#deposit-limit-sga-rg-increase").hide(); $("#editlimits").show(); $("#deposit-limit-intro").show(); $("#deposit-limit-sga-period-info").show(); }); } }); function processSGADepositLimitSelections(){ var daily = 0, weekly = 0, monthly = 0; var period = $('#period option:selected').val(); var value = $('#value').val(); daily = value; var limit_set = $("#value").data("default"); function updateSgaDepositLimitMessageVisibility(selectedDepositLimitValue) { var sgaDepositLimitThreshold = 5000; var parsedValue = parseInt(selectedDepositLimitValue, 10); var sgaDepositLimitsNoticeMessageShown = parsedValue > sgaDepositLimitThreshold; if(sgaDepositLimitsNoticeMessageShown) { $('#sga-deposit-limits-notice-message').show(); } else { $('#sga-deposit-limits-notice-message').hide(); } } if(value) { // updateSgaDepositLimitMessageVisibility(value); if(period){ switch(period) { case 'daily': weekly = value * 7; monthly = value * 28; break; case 'weekly': weekly = value; monthly = value * 4; break; case 'monthly': weekly = value; monthly = value; break; } $("#period_daily_amount").html(daily); $("#period_weekly_amount").html(weekly); $("#period_monthly_amount").html(monthly); $("#deposit-limit-sga-period-info").show(); var current_period = $('#period').attr('data-period'); var current_value = $('#value').attr('data-value')*1; var new_value_converted = $("#period_"+current_period+"_amount").html()*1; if(limit_set && monthly >= 10000){ reason = 'init10k'; toggleSubmit(false, '#generic-submit'); $("#deposit-limit-submit").hide(); recordDOCAction(); $("#deposit-limit-sga-duty-of-care").show(); } else if(new_value_converted > current_value){ toggleSubmit(false, '#generic-submit'); $("#deposit-limit-submit").hide(); recordDOCAction(); $("#deposit-limit-sga-duty-of-care").show(); } else{ $("#deposit-limit-sga-duty-of-care").hide(); $("#deposit-limit-submit").show(); toggleSubmit(true, '#generic-submit'); } } } } function recordDOCAction(){ callPlatformAPI('responsible-gambling-action', { actionType : 'sga-doc' }).then(function(response) { actionid = response.actionId; }); } function recordDOCAudit(actionid, type, message){ callPlatformAPI('responsible-gambling-audit', { actionId : actionid, auditType : type, message : message }); } function toggleSubmit(toggle, id){ var mobileAction = toggle ? 'enable' : 'disable'; if ($.mobile) { //required for jquery mobile! $(id).button().button(mobileAction); } else{ $(id).prop('disabled', !toggle); } } $(document).ready(function() { // Make sure the kyc link is handled as normal as possible, needed as some site overwrite the default behaviour. // E.g. https://github.com/whitehatgaming/site-grandivy/blob/7c716173a42dc52e68c536dcbf0f1eb1a7124cbc/js-source/extras.js#L340 window.addEventListener('click', e => { if (e.defaultPrevented && e.target.matches('#my-account-modal .user-details-kyc-redirect')) { if (e.target.target) { window.open(e.target.href, e.target.target); } else { window.location.href = e.target.href; } } }); }); $(document).ready(function() { setDepositLimitsFormCustomValidationMessages(); setSelfExcludeFormCustomVaildationMessages(); setTimeOutFormCustomVaildationMessages(); }); function setValidationMessage(el, validationErrorMap) { function findValidationMessage() { var validationKeys = Object.keys(validationErrorMap); for (var i = 0; i < validationKeys.length; i++) { if (el.validity[validationKeys[i]]) { return validationErrorMap[validationKeys[i]]; }; }; return undefined; }; /** * Update element title tooltip */ el.onmouseover = function() { var validationMsg = findValidationMessage(); $(this).title = validationMsg || ''; }; /** * Update validation message */ [ 'oninput', 'onchange', 'oninvalid' ].forEach(function(methodKey) { el[methodKey] = function() { var validationMsg = findValidationMessage(); el.setCustomValidity(validationMsg || ''); }; }); }; function setValidationCustomMessages(validationErrorConfig) { validationErrorConfig.filter(function(el) { var elementDefined = Boolean(el[0]); return elementDefined; }).forEach(function(elValidationSet) { var el = elValidationSet[0]; var validationErrorMap = Object.keys(elValidationSet[1]).reduce(function (validationMessages, currentKey) { if (elValidationSet[1][currentKey] && elValidationSet[1][currentKey].indexOf('UNDEFINED_LANGUAGE_KEY') < 0) { validationMessages[currentKey] = elValidationSet[1][currentKey]; } return validationMessages; }, {}); setValidationMessage(el, validationErrorMap); }); } function setDepositLimitsFormCustomValidationMessages() { var requiredAttr = 'data-validation-message-required'; var minAttr = 'data-validation-message-min' var maxAttr = 'data-validation-message-max' var periodSelectEl = $('#editlimits #period'); var amountInputEl = $('#editlimits #value'); var passwordInputEl = $('#editlimits #password'); var periodValidationMessageRequired = periodSelectEl.attr(requiredAttr); var amountValidationMessageRequired = amountInputEl.attr(requiredAttr); var amountValidationMessageMin = amountInputEl.attr(minAttr); var amountValidationMessageMax = amountInputEl.attr(maxAttr); var passwordValidationMessageRequired = passwordInputEl.attr(requiredAttr); /** * Passing first item of the jQuery (e.g. periodSelectEl[0]) picked element, * since it contains the native html element. */ var validationErrorConfig = [ [periodSelectEl[0], { valueMissing: periodValidationMessageRequired }], [amountInputEl[0], { valueMissing: amountValidationMessageRequired, rangeUnderflow: amountValidationMessageMin, rangeOverflow: amountValidationMessageMax }], [passwordInputEl[0], { valueMissing: passwordValidationMessageRequired }], ]; setValidationCustomMessages(validationErrorConfig); }; function setSelfExcludeFormCustomVaildationMessages() { var requiredAttr = 'data-validation-message-required'; var periodSelectEl = $('#selfexclude-form #seperiod'); var usernameInputEl = $('#selfexclude-form #seusername'); var passwordInputEl = $('#selfexclude-form #sepassword'); var periodValidationMessageRequired = periodSelectEl.attr(requiredAttr); var usernameValidationMessageRequired = usernameInputEl.attr(requiredAttr); var passwordValidationMessageRequired = passwordInputEl.attr(requiredAttr); /** * Passing first item of the jQuery (e.g. periodSelectEl[0]) picked element, * since it contains the native html element. */ var validationErrorConfig = [ [periodSelectEl[0], { valueMissing: periodValidationMessageRequired }], [usernameInputEl[0], { valueMissing: usernameValidationMessageRequired, }], [passwordInputEl[0], { valueMissing: passwordValidationMessageRequired }], ]; setValidationCustomMessages(validationErrorConfig); } function setTimeOutFormCustomVaildationMessages() { var requiredAttr = 'data-validation-message-required'; var periodSelectEl = $('#timeout-form #period'); var passwordInputEl = $('#timeout-form #password'); var periodValidationMessageRequired = periodSelectEl.attr(requiredAttr); var passwordValidationMessageRequired = passwordInputEl.attr(requiredAttr); /** * Passing first item of the jQuery (e.g. periodSelectEl[0]) picked element, * since it contains the native html element. */ var validationErrorConfig = [ [periodSelectEl[0], { valueMissing: periodValidationMessageRequired }], [passwordInputEl[0], { valueMissing: passwordValidationMessageRequired }], ]; setValidationCustomMessages(validationErrorConfig); }const observedItems = ["category-list", "game-element", "provider-list"]; $(window).on("load", async () => { await waitForAllElements(observedItems); setOnClickListeners(); }); function waitForAllElements(items) { return new Promise((resolve) => { const selectors = items.map((item) => `[data-observer="${item}"]`); const observer = new MutationObserver(() => { const foundElements = selectors.map((selector) => $(selector).get(0)).filter(Boolean); const allElementsFound = foundElements.length === selectors.length; if (allElementsFound) { observer.disconnect(); resolve(foundElements); } }); observer.observe(document.body, { attributes: true, childList: true, subtree: true }); }); } function setOnClickListeners() { $('[data-observer="category-list"]').on('click', function(event) { const category = $(event.target).closest("[data-category]").data("category"); if (category) { const formattedCategory = category.toLowerCase().replace(/\s+/g, '-'); updateURLParams('category', formattedCategory); removeURLParam('provider'); } event.stopPropagation(); }); $('[data-observer="provider-list"]').on('click', function(event) { const provider = $(event.target).closest("[data-provider]").data("provider"); if (provider) { const formattedProvider = provider.toLowerCase().replace(/\s+/g, '-'); updateURLParams('provider', formattedProvider); updateURLParams('category', "provider"); } event.stopPropagation(); }); } function updateURLParams(paramName, paramValue) { const url = new URL(window.location.href); url.searchParams.set(paramName, paramValue); window.history.replaceState(null, null, url); } function removeURLParam(paramName) { const url = new URL(window.location.href); url.searchParams.delete(paramName); window.history.replaceState(null, null, url); }class SharedGamesAPI { constructor() { this.jurisdiction = $('body').attr('data-jurisdiction') || "mga"; this.language = $('body').attr('data-language') || "en"; this.country = $('body').attr('data-country') || ""; this.brandID = 84; this.isMobile = false; this.deviceType = this.isMobile ? "MobileHTML" : "Desktop"; this.currencySymbol = "€"; this.currency = "EUR"; this.imagePath = "\/\/scontent-wh.whitehatgaming.com\/images\/portrait\/"; } cacheTime = 720; //Cache time setImagePath(path) { this.imagePath = path; return this; } getBlockUnfunded(){ let blockUnfunded = false; if(this.country == 'GB'){ blockUnfunded = true; const isGBuser = $('body').attr('data-isGBuser') || false; const isfunded = $('body').attr('data-isfunded') || false; if(isGBuser == 'true' && isfunded == 'true'){ blockUnfunded = false; } } return blockUnfunded; } async fetchGamesData(brandID, deviceType, sort, provider) { let blockUnfunded = this.getBlockUnfunded(); let data = { brandId: brandID || this.brandID, language: this.language, country: this.country, jurisdiction: this.jurisdiction, blockUnfunded: blockUnfunded, device: deviceType || this.deviceType }; if(sort){ data.sortBy = sort; } if(provider){ data.providerTitle = provider; } if(USER_FLAG_TEST_GAMES){ data.testMode = true; } try { const gamesDataURL = `${GAMES_API}/games`; const gamesData = await $.ajax({ type: 'GET', url: gamesDataURL, dataType: 'json', contentType: 'application/json', data: data }); return gamesData; } catch (error) { console.error("Error fetching games data:", error); throw new Error("Failed to fetch games data"); } } async fetchCategoriesData(brandID, deviceType) { try { const categoryDataURL = `${GAMES_API}/game-categories/brands/${brandID || this.brandID}`; const categoryData = await $.ajax({ type: 'GET', url: categoryDataURL, data: { device: deviceType || this.deviceType }, dataType: 'json' }); return categoryData; } catch (error) { console.error("Error fetching category data:", error); throw new Error("Failed to fetch category data"); } } resolveGameDataCache(gameUrl){ return new Promise(function (resolve) { caches.has('GamesCache').then(function (hasCache) { if (!hasCache) { resolve(null); throw new Error("GamesCache not found"); } else { caches.open('GamesCache').then(function (cache) { cache.match(gameUrl).then(function (res) { if (res === undefined) { resolve(null); throw new Error("Cache " + gameUrl + " not found"); } return res.json(); }).then(function (games) { resolve(games); }).catch(function(){}); }); } }).catch(function(){}); }); } resolveCategoryDataCache(categoryUrl){ return new Promise(function (resolve) { caches.has('CategoriesCache').then(function (hasCache) { if (!hasCache) { resolve(null); throw new Error("CategoriesCache not found"); } else { caches.open('CategoriesCache').then(function (cache) { cache.match(categoryUrl).then(function (res) { if (res === undefined) { resolve(null); throw new Error("Cache " + categoryUrl + " not found"); } return res.json(); }).then(function (categories) { resolve(categories); }).catch(function(){}); }); } }).catch(function(){}); }); } async processGameData(brandID, deviceType, sort, provider) { brandID = brandID || this.brandID; deviceType = deviceType || this.deviceType; let sortBy; if(sort){ if (!['az', 'recent', 'rtp', 'top', 'mobiletop'].includes(sort)) { console.warn(`Sort option "${sort}" not supported`); } if(sort == 'az'){ sortBy = 'name'; } else if(sort == 'recent'){ sortBy = 'createdAt'; } else if(sort == 'rtp'){ sortBy = sort; } else if(sort == 'top' || sort == 'mobiletop'){ sortBy = 'mostPopular'; } } try { const cache = $('body').attr('data-cache'); let blockUnfunded = this.getBlockUnfunded(); if(cache == '1'){ if(sortBy){ sortBy = '&sortBy='+sortBy; } else if(sortBy === undefined) sortBy=''; if(provider){ provider = '&providerTitle='+provider; } else if(provider === undefined) provider=''; let testMode = ''; if(USER_FLAG_TEST_GAMES){ testMode = '&testMode=true'; } this.deleteOldCache(); let gameUrl = `${GAMES_API}/games?brandId=${brandID}&language=${this.language}&country=${this.country}&jurisdiction=${this.jurisdiction}&blockUnfunded=${blockUnfunded}&device=${deviceType}${sortBy}${provider}${testMode}`; let categoryUrl = `${GAMES_API}/game-categories/brands/${brandID}?device=${deviceType}`; this.addToGameCache(gameUrl); const resGameData = this.resolveGameDataCache(gameUrl); this.addToCategoryCache(categoryUrl); const resCategoryData = this.resolveCategoryDataCache(categoryUrl); return resGameData.then(async retGames => { return resCategoryData.then(async retCategories => { let categories = null; let games = null; if(retCategories != null){ categories = retCategories; } else{ categories = await this.fetchCategoriesData(brandID, deviceType); } if(retGames != null){ return this.parseResponse(retGames,categories,deviceType); } else{ games = await this.fetchGamesData(brandID, deviceType, sortBy, provider); return this.parseResponse(games,categories,deviceType); } }); }); } else{ let categories = await this.fetchCategoriesData(brandID, deviceType); let games = await this.fetchGamesData(brandID, deviceType, sortBy, provider); return this.parseResponse(games,categories,deviceType); } } catch (error) { console.error("Error processing game and categories data:", error); throw new Error("Failed to process game and categories data"); } } parseResponse(gamesData,categoriesData,deviceType){ let processedGameData = { categories: [], games: [], gamesByProvider: [], providers: [], providerKeys: [], searchResults: [] }; const gamesByCategory = []; const gamesWithProperties = []; const uniqueProviders = {}; const uniqueProviderKeys = {}; const currencySymbol = $('body').attr('data-currency-symbol') || $('body').attr('data-cursym') || this.currencySymbol; const currency = $('body').attr('data-currency-name') || $('body').attr('data-currency') || this.currency; const imageURL = $('body').attr('data-img-url') || this.imagePath; const categoriesById = {}; categoriesData.forEach((category) => categoriesById[category.id] = category); gamesData.forEach((gameData) => { var launch = `javascript:launchGame(800, 600, '${gameData.game.launchCode}')`; if(deviceType == "MobileHTML"){ if(gameData.game.distributor == 'iGaming2Go'){ launch = `javascript:launchGame(800, 600, '${gameData.game.launchCode}','3')`; } else{ launch = `javascript:launchGame(800, 600, '${gameData.game.launchCode}','2')`; } } const gameObj = { title: gameData.game.name, name: gameData.game.name, description: gameData.game.description, code: gameData.game.launchCode, launchcode: gameData.game.launchCode, image: `${imageURL + gameData.game.imageBackground}.webp`, provider: gameData.game.providerTitle, providerKey: gameData.game.provider, launch: launch, curSym: currencySymbol, currency: currency, jackpot: gameData.game.jackpot, date_added: gameData.game.updatedAt, rtp: gameData.game.rtp, categories: gameData.categories, jurisdictions: gameData.jurisdictions, subCategory_code: gameData.gameTags, seoName: gameData.game.seoName, fun_supported: gameData.game.funSupported, ghot: (gameData?.gameTags.includes("hot") ? 1:0), gnew: (gameData?.gameTags.includes("new") ? 1:0) }; uniqueProviders[gameObj.provider] = true; uniqueProviderKeys[gameObj.providerKey] = true; gameData.categories.forEach((gameCategory) => { const categoryId = gameCategory.id; if (categoryId) { const matchingCategory = categoriesById[categoryId]; if (matchingCategory) { const existingCategoryIndex = gamesByCategory.findIndex((cat) => cat.category_id === matchingCategory.id); const matchingGameCategory = gameObj.categories.find(cat => cat.id === matchingCategory.id); if (existingCategoryIndex === -1) { gamesByCategory.push({ code: matchingCategory.name, category_id: matchingCategory.id, games: [{ ...gameObj, category_code: matchingCategory.name, category_title: matchingCategory.title, sequence: matchingGameCategory.seq }], title: matchingCategory.title, seq: matchingCategory.seq }); } else { gamesByCategory[existingCategoryIndex].games.push({ ...gameObj, category_code: matchingCategory.name, category_title: matchingCategory.title, sequence: matchingGameCategory.seq }); gamesByCategory[existingCategoryIndex].games.sort((a, b) => (a.sequence || 0) - (b.sequence || 0)); } } else { console.warn("Game", gameObj.title, "has an invalid category ID"); } } else { console.warn("Game", gameObj.title, "does not have a valid category ID"); } }); gamesWithProperties.push(gameObj); }); const uniqueGames = gamesWithProperties; const uniqueProvidersArray = Object.keys(uniqueProviders); const uniqueProviderKeysArray = Object.keys(uniqueProviderKeys); gamesByCategory.sort((a, b) => a.seq - b.seq); processedGameData.categories = gamesByCategory; processedGameData.games = uniqueGames; processedGameData.providers = uniqueProvidersArray; processedGameData.providerKeys = uniqueProviderKeysArray; processedGameData.gamesByProvider = this.groupBy(uniqueGames, 'provider'); return processedGameData; } filterGamesByCategory(processedGameData, categoryCode) { if (!processedGameData || !processedGameData.categories) { console.error("Processed game data or categories not found."); return []; } const gamesByCategory = processedGameData.categories.find(cat => cat.code === categoryCode); if (!gamesByCategory) { console.warn(`No games found for category code: ${categoryCode}`); return []; } return gamesByCategory.games || []; } groupBy(array, prop) { return array.reduce(function(groups, item) { var existIndex = groups.findIndex(function(elem) { return elem.title === item[prop]; }); if (existIndex !== -1) { groups[existIndex].games.push(item); } else { groups.push({ title: item[prop], code: item[prop].toLowerCase().replace(/ /g, '-'), games: [item] }); } return groups; }, []); } // Cache AllGames locally addToGameCache(gameUrl) { var options = { method: 'GET', headers: new Headers({ 'Content-Type': 'application/json', }), }; var hoursGame = moment().diff(moment(localStorage.getItem('cachedGameTime')), 'minutes'); if(hoursGame > this.cacheTime || isNaN(hoursGame)){ localStorage.setItem('cachedGameTime', Date()); // Simple Timer for GamesCache } caches.open('GamesCache').then(function (cache) { cache.add( gameUrl, options ); }); } // Cache AllGames locally addToCategoryCache(gameUrl) { var options = { method: 'GET', headers: new Headers({ 'Content-Type': 'application/json', }), }; var hoursCategory = moment().diff(moment(localStorage.getItem('cachedCategoryTime')), 'minutes'); if(hoursCategory > this.cacheTime || isNaN(hoursCategory)){ localStorage.setItem('cachedCategoryTime', Date()); // Simple Timer for CategoryCache } caches.open('CategoriesCache').then(function (cache) { cache.add( gameUrl, options ); }); } // Refresh Cached Games and Categories if Older than 12 hours deleteOldCache() { if (localStorage.getItem('cachedGameTime')) { var hoursGame = moment().diff(moment(localStorage.getItem('cachedGameTime')), 'minutes'); if (hoursGame > this.cacheTime) { caches.delete('GamesCache'); } } else{ // If GamesCache exists but isn't timed, delete. caches.delete('GamesCache'); } if (localStorage.getItem('cachedCategoryTime')) { var hoursCategory = moment().diff(moment(localStorage.getItem('cachedCategoryTime')), 'minutes'); if (hoursCategory > this.cacheTime) { caches.delete('CategoriesCache'); } } else { // If CategoriesCache exists but isn't timed, delete. caches.delete('CategoriesCache'); } } } const LOSS_LIMITS_FIELDS = ["#editlimits #generic-submit", "#editlimits #period", "#editlimits #value", "#editlimits #loss-limit-password"]; const LOSS_LIMITS_PAGE = "/?page=losslimit"; $(document).ready(function () { $("body").on("submit", ".loss-limit ", function (event) { var lang = getCookie("language") || "en"; var lossLimitTranslations = { en: { titleCoolOff: "Cool off period request", messageCoolOff: "Your request gets in a 24 hour cool off period.", titleSuccessUpdate: "Loss limits", messageSuccessUpdate: "Your loss limits have been successfully updated.", areYouSureTitle: "Are you sure?", areYouSureYes: "Yes", areYouSureNo: "No", }, fr: { titleCoolOff: "Demande de période de réflexion", messageCoolOff: "Votre demande entre dans une période de réflexion de 24 heures", titleSuccessUpdate: "Limites de pertes", messageSuccessUpdate: "Vos limites de perte ont été mises à jour avec succès.", areYouSureTitle: "Êtes-vous sûr?", areYouSureYes: "Oui", areYouSureNo: "Non", }, }; var thisForm = $(this); var returnUrl = null; event.preventDefault(); var formData = thisForm.serialize(); var sender = formData.split("sender=")[1].split("&")[0]; var doSubmit = function () { toggleFields(); showMainLoader(); $("#edit-status").text(""); var formData = thisForm.serialize(); var payload = {}; var sender = formData.split("sender=")[1].split("&")[0]; var slugCall = "-update"; switch (sender) { case "confirm": case "cancel": actionId = formData.split("ref=")[1].split("&")[0]; payload = { sessionid: getCookie("sid"), action: parseInt(actionId), }; slugCall = "-" + sender; break; default: payload = { password: $("#loss-limit-password").val(), sessionid: getCookie("sid"), rglosslimit: { period: $("#period").val(), value: parseInt($("#value").val()), }, }; break; } callPlatformAPI("rgloss-limit" + slugCall, payload) .then(function (data) { function continueToNormalFlow() { hideMainLoader(); if (data.type != "error") { msg = data.message; returnUrl = data.returnUrl ?? LOSS_LIMITS_PAGE; $(".hide-on-success").hide(); thisForm[0].reset(); if (formData.indexOf("timeout") > -1) { $(".modal-body .back-button, .modal-header .close, .modal-backdrop").click(function (e) { e.preventDefault(); $("#my-account-modal").modal("hide"); location.reload(); }); $(".modal-content").click(function (e) { e.stopPropagation(); }); } } else { msg = data.message; } setStatusMsg("edit-status", msg, data.status); $(".deposit-limits-fields-container #edit-status").html(msg); if (data.type != "error") { $(".deposit-limits-fields-container #edit-status").addClass("success").removeClass("error"); var sender = formData.split("sender=")[1].split("&")[0]; var isConfirm = sender == "confirm"; var isUpdate = sender == "change"; var isCancel = sender == "cancel"; var confirmSuccess = false; var hasCoolOff = false; var updateCurrentDepositLimit = function () { $.ajax({ type: "GET", url: "/ajax/ajaxhandler.php", data: { req: "losslimit", sender: "current", }, dataType: "json", encode: true, }) .done(function (data) { const successMessage = lossLimitTranslations[lang].messageSuccessUpdate; if (isConfirm) { // delete previous pending status item, as has been updated in db. const item = $(".limit-history-modal-list-item") if (item) { item[0]?.remove(); } } // update limit history var newLimitHistoryItemHTML = data["latestlimithtml"] ? data["latestlimithtml"] : ""; $(".limit-history-modal-list").prepend(newLimitHistoryItemHTML); $(".limit-history-no-result-list-item").remove(); if (!is_mobile) { var buttonText = returnUrl ? "continue" : "ok"; popup( "300", lossLimitTranslations[lang].titleSuccessUpdate, "

" + successMessage + "

", "true", "false", null, buttonText, returnUrl ); } else { if (!alert(successMessage)) { window.location.href = returnUrl; } } var currentLimit = data["current_loss_limit"]; $("#limitCurrent").html("Current Deposit Limit : " + currentLimit); $("#period").attr("value", data?.rglosslimit?.period); $("#value").attr("value", data?.rglosslimit?.value); }) .fail(function (er) { console.warn("error:", er); toggleFields(false); }); }; if (isConfirm) { confirmSuccess = data.status; } if (isUpdate) { if (data.cooloff != 1) { updateCurrentDepositLimit(); } else { $("#editlimits") .find("input, select") .each(function () { $(this).attr("disabled", "disabled"); }); popup( "300", lossLimitTranslations[lang].titleCoolOff, "" + lossLimitTranslations[lang].messageCoolOff + "", "true", "false", "false", null, "/account" ); } } else { $("#pendingAndCoolOff").hide(); // Enable all fields if (is_mobile) { $("#editlimits .deposit-limits-fields-container") .find(".input-div>div>div, .input-div>input, .action>div") .each(function () { $(this).attr("aria-disabled", "false"); $(this).removeClass("ui-disabled"); }); } $("#editlimits") .find("input, select") .each(function () { $(this).removeAttr("disabled"); }); } } else { $(".deposit-limits-fields-container #edit-status").addClass("error").removeClass("success"); } } continueToNormalFlow(); }) .fail(function (data) { hideMainLoader(); setStatusMsg("edit-status", "Internal error has occured, please contact support", false); console.warn("error:", data); }); }; var _this = this; var isInIframe = window.location != window.parent.location, targetDocument = isInIframe ? window.parent.document : window.document; if ($(this).attr("id").indexOf("cancellimits") > -1 || $(this).attr("id").indexOf("confirmlimits") > -1) { var message = '"; popup("300", lossLimitTranslations[lang].areYouSureTitle, message, "false"); var isInIframe = window.location != window.parent.location, targetDocument = isInIframe ? window.parent.document : window.document; $("#popupConfirmCancelDepositLimit a", targetDocument).click((e) => { e.preventDefault(); doSubmit.call($(_this)); $('#popupBox', targetDocument).remove(); $('#overlay', targetDocument).hide(); }); $("#popupCancelCancelDepositLimit a", targetDocument).click((e) => { e.preventDefault(); $('#popupBox', targetDocument).remove(); $('#overlay', targetDocument).hide(); }); } else { doSubmit.call($(_this)); } }); }); function toggleFields(disableFields = true) { LOSS_LIMITS_FIELDS.forEach((field) => { $(field).prop("disabled", disableFields); }); $("#editlimits #loading-button").toggle(); $("#editlimits #generic-submit").toggle(); } $(document).ready(() => { if (window.location.href.includes("page=unsubscribe") || $('body').data('whg-page-id') === 'unsubscribe') { const urlParams = new URLSearchParams(window.location.search); const type = urlParams.get("type"); const token = urlParams.get("token"); if (!token || !type) { window.location.href = "/"; } else { checkUnsubscribeType(type); unsubscribeEmail(type, token); } } $("#unsubscribe-form button").attr("disabled", true); $("#unsubscribe-form").submit((e) => { e.preventDefault(); const type = $(this).data("type"); const token = $(this).data("token"); const preference = $(this).serializeArray()[0].value; const payload = { token: token, marketingPrefs: {}, }; if (preference === "all") { payload.marketingPrefs.crossMarketing = {}; payload.marketingPrefs.brandMarketing = {}; payload.marketingPrefs.brandMarketing[type] = false; payload.marketingPrefs.crossMarketing[type] = false; } else { payload.marketingPrefs[preference] = {}; payload.marketingPrefs[preference][type] = false; } callPlatformAPI("user-marketing-update", payload).then((response) => { if (response.type === "error") { showMarketingError(response.message); return; } $("#unsubscribe-step-1").addClass("hidden"); $("#unsubscribe-step-2").removeClass("hidden"); }); }); $("#unsubscribe-form input").change((event) => { $('#unsubscribe-form button[type="submit"]').removeAttr("disabled"); }); }); function unsubscribeEmail(type, token) { // Define mapping of unsubscribe types to their corresponding preference key and channel const UNSUBSCRIBE_TYPE_CONFIG = { email: { preferenceKey: 'brandMarketing', channel: 'email' }, xemail: { preferenceKey: 'crossMarketing', channel: 'email' }, cross: { preferenceKey: 'crossMarketing', channel: 'email' }, sportsemail: { preferenceKey: 'sportsBrandMarketing', channel: 'email' }, sportscross: { preferenceKey: 'sportsCrossMarketing', channel: 'email' }, sms: { preferenceKey: 'brandMarketing', channel: 'sms' }, crosssms: { preferenceKey: 'crossMarketing', channel: 'sms' }, sportssms: { preferenceKey: 'sportsBrandMarketing', channel: 'sms' }, sportscrosssms: { preferenceKey: 'sportsCrossMarketing', channel: 'sms' } }; const config = UNSUBSCRIBE_TYPE_CONFIG[type]; if (!config) { console.warn('[unsubscribeEmail] type not supported', type); return }; const payload = { token: token, marketingPrefs: { [config.preferenceKey]: { [config.channel]: false, } } }; callPlatformAPI("user-marketing-update", payload).then((response) => { if (response.type === "error") { showMarketingError(response.message); return; } showSuccessMessage(); }); } function checkUnsubscribeType(type) { const validEmailTypes = ['email', 'cross', 'sportsemail', 'sportscross']; const validSmsTypes = ['sms', 'crosssms', 'sportssms', 'sportscrosssms']; if (validEmailTypes.includes(type) || validSmsTypes.includes(type)) { return $("#unsubscribe-email").show(); } if (type === "xemail") { return $("#unsubscribe-xemail").show(); } $("#unsubscribe-container").show(); } function showMarketingError(msg) { $(".marketing_prefs_error_msg").append(msg); $(".marketing_prefs_error").show(); $(".email-container").hide(); } function showSuccessMessage() { $(".email-success").show(); } $(document).ready(function() { // Block checking an email/phone channel when the contact field is not yet set $('body').on('change', '#user-marketing-preferences input[type=checkbox]', function() { if (!window.contactMissingFields || !$(this).prop('checked')) { return; } var missing = window.contactMissingFields; var isEmailChannel = $(this).attr('name') === 'receiveEmail'; var isPhoneChannel = $(this).attr('name') === 'receiveSms' || $(this).attr('name') === 'receivePhone'; if ((isEmailChannel && missing.email) || (isPhoneChannel && missing.phone)) { $(this).prop('checked', false); var msg = isEmailChannel ? missing.errorEmail : missing.errorPhone; $('#marketing-preferences-status').text(msg).css('color', '#d32f2f').show(); $('#contact-input-section').show(); } }); // Update user notifications $('body').on('submit', '#user-marketing-preferences', function(event) { event.preventDefault(); $('#edit-notification-status').text(""); showMainLoader(); var brandMarketingFields = $('fieldset[name=brand-marketing-preferences]'); var crossMarketingFields = $('fieldset[name=cross-marketing-preferences]'); var formData = { marketingPrefs: { brandMarketing: { sms: $('input[name=receiveSms]', brandMarketingFields).prop('checked'), phone: $('input[name=receivePhone]', brandMarketingFields).prop('checked'), post: $('input[name=receivePost]', brandMarketingFields).prop('checked'), email: $('input[name=receiveEmail]', brandMarketingFields).prop('checked'), }, crossMarketing: { sms: $('input[name=receiveSms]', crossMarketingFields).prop('checked'), phone: $('input[name=receivePhone]', crossMarketingFields).prop('checked'), post: $('input[name=receivePost]', crossMarketingFields).prop('checked'), email: $('input[name=receiveEmail]', crossMarketingFields).prop('checked'), } } } callPlatformAPI('user-marketing-update', formData).then((response) => { if (response.type === 'error'){ return showMarketingError(response.message, response.code); } if ($('#user-marketing-preferences .action > div').length) { $('#user-marketing-preferences .action > div').addClass('ui-disabled'); } else { $('#user-marketing-preferences input[type="submit"]').attr('disabled', true); } setStatusMsg("marketing-preferences-status", "Your account details have been successfully updated.", true); }) .fail(function() { setStatusMsg("marketing-preferences-status", "

There was a problem updating your account details.

Error: Unknown

", true); }) .always(function() { hideMainLoader(); }) }); function showMarketingError(msgFallback, code){ const errorMessages = { 306: "Preference not saved: email and/or phone is missing. Please add your details before updating your communication preferences.", 307: "Preference not saved: email and/or phone is missing. Please add your details before updating your communication preferences." } const message = errorMessages[code] || msgFallback const prefixMessage = "

There was a problem updating your account details.

Error:

" setStatusMsg("marketing-preferences-status", prefixMessage + message, true); } }); $(document).ready(function(){ var crossDiv = $(".marketing_prefs_cross_hide"); var sureDiv = $('#marketing_prefs_optout_check'); var stepCookie = 'marketing_prefs_email'; //Check if stepCookie is set and skip first step if so. var cookieVal = getCookie(stepCookie); if(typeof cookieVal != 'undefined'){ $("input[name=email][value=" + cookieVal + "]").prop('checked', true); $('#marketing_prefs_laws').hide(); $('#marketing_prefs_part1').hide(); $('#marketing_prefs_part2').show(); } //Marketing prefs clicked - show hide cross marketing form. $(".optin").change(function() { var showCross = false; $('input.optin:checkbox').each(function(){ if(this.checked){ showCross = true; return; } }); if(showCross){ crossDiv.show(); sureDiv.hide(); updateMarketingCheckboxes($('#optout')); toggleMarketingSubmit($('input:radio[name="cross"]').is(':checked'), '', 2); } else{ crossDiv.hide(); toggleMarketingSubmit(false, '', 2); } }); //Opt out clicked, untick other options and hide cross marketing. $("#optout").change(function() { if(this.checked){ updateMarketingCheckboxes($('input.optin:checkbox')); crossDiv.hide(); sureDiv.show(); toggleMarketingSubmit(true, '', 2); } else{ sureDiv.hide(); toggleMarketingSubmit(false, '', 2); } }); //Cross marketing selected, enable button. $('input:radio[name="cross"]').change(function() { if (this.checked) { toggleMarketingSubmit(true, '', 2); } }); //Email Yes/No Step1, enable button. $('input:radio[name="email"]').change(function() { if (this.checked) { toggleMarketingSubmit(true, 1); } }); //Law continue clicked on. $('#prefs_law_continue').click(function () { $('#marketing_prefs_laws').hide(); $('.'+$(this).data( "show" )).show(); document.body.scrollTop = document.documentElement.scrollTop = 0; }); //Two step - email no selected - are you sure? $('.email_optin').change(function(){ if(this.checked && this.value == 'no'){ $('#marketing_prefs_email_optout_check').show(); } else{ $('#marketing_prefs_email_optout_check').hide(); } }); //Two step email chosen. $('#prefs_update1').click(function () { setCookie(stepCookie,$('input:radio[name="email"]:checked').val(),365); $('#marketing_prefs_part1').hide(); $('#marketing_prefs_part2').show(); document.body.scrollTop = document.documentElement.scrollTop = 0; }); //? pressed on mobile. $('#prefs_cross_help').click(function() { var extraModalContainerClass = 'marketing-prefs-casino-family-explanation-popup'; popup( 300, "", '

'+decodeURIComponent(($(this).data('help')+'').replace(/\+/g, '%20'))+'

', 'true', 'false', extraModalContainerClass ); }); //Update (all) user settings. $('#prefs_update').click(function () { $('#marketing_prefs_error').hide(); var brandPrefs = {}; var crossPrefs = {}; var brandOptedIn = $('input#optout:checked').length == 0; var crossOptedIn = $('input:radio[name="cross"]:checked').val() == "yes"; var redirect = true; var redirectUrl = $(this).data('redirect-url') || "/"; $('input.optin:checkbox').each(function(){ brandPrefs[this.id] = this.checked; crossPrefs[this.id] = crossOptedIn ? this.checked : false; }); if($(this).data('sender') == 'step2'){ brandPrefs['email'] = $('input:radio[name="email"]:checked').val() == "yes" || typeof cookieVal != 'undefined' ? true : false; crossPrefs['email'] = crossOptedIn ? brandPrefs['email'] : false; } var ack = { 'marketingPrefs' : { 'brandMarketing': brandPrefs, 'crossMarketing': crossPrefs } }; if($('#token').val() != ''){ redirect = false; ack['token'] = $('#token').val(); } callPlatformAPI("user-marketing-update", ack) .done(function(data) { if (data.type == 'error') { showMarketingError(data.message, data.code); } else { removeCookie(stepCookie); if (redirect) { window.location.href = redirectUrl; } else { showMarketingUpdated(); } } }) .fail(function() { showMarketingError('Unknown error occurred.'); }) }); function showMarketingError(msgFallback, code){ const errorMessages = { 306: "Preference not saved: email and/or phone is missing. Please add your details before updating your communication preferences.", 307: "Preference not saved: email and/or phone is missing. Please add your details before updating your communication preferences." } const message = errorMessages[code] || msgFallback $('#marketing_prefs_error_msg').empty(); $('#marketing_prefs_error_msg').append(message); $('#marketing_prefs_error').show(); } function showMarketingUpdated(){ $('.marketing_prefs_succss_hide').hide(); $('#marketing_prefs_success').show(); document.body.scrollTop = document.documentElement.scrollTop = 0; } function toggleMarketingSubmit(toggle, id='', step=""){ toggle = marketingSubmitValidation(toggle, step); var mobileAction = toggle ? 'enable' : 'disable'; if ($.mobile) { //required for jquery mobile! $('#prefs_update'+id).button().button(mobileAction); } else{ $('#prefs_update'+id).prop('disabled', !toggle); } } function updateMarketingCheckboxes(element){ if ($.mobile) { //required for jquery mobile! try{ element.prop('checked', false).checkboxradio('refresh'); }catch(err){ element.prop('checked', false); } }else{ element.prop('checked', false); } } function marketingSubmitValidation(toggle, step) { var twostep = $(".marketing-prefs-two-steps-modal").length > 0; // init variables for step 2 check var optin = $('input.optin:checkbox:checked').length > 0; var optout = $('input#optout:checked').length > 0; var cross = $('input:radio[name="cross"]:checked').length > 0; // if twostep template, step == 2 and one of the selections missing, disable submit. if( twostep && step==2 && !((optin || optout) && cross) ) { toggle = false; } return toggle; } }); $(document).ready(function(){ sendUserDataToApp(); function sendUserDataToApp(){ var data = { "userid" : "", "username" : "" } if ("Android" in window && typeof Android.updateXtremePushData === 'function' && isLoggedIn) { Android.updateXtremePushData(JSON.stringify(data)); } else if(window.webkit && window.webkit.messageHandlers && isLoggedIn){ try{ webkit.messageHandlers.xtremepush.postMessage(data); }catch(err) { console.log('The native context does not exist yet'); } } } });$(document).ready(function() { // MYACCOUNT // Update user notifications $('body').on('change', '#toggleOTPform input[name=otp]', function(event) { event.preventDefault(); $('#toggle-otp-status').text(""); showMainLoader(); // done this way to prevent ide complaints of php syntax in js file, while still serving int var userId = parseInt("0"); var formData = { settings: { "two-factor-required": $('#toggleOTPform input[name=otp]').prop('checked'), }, userId : userId, } callPlatformAPI('user-security-settings/update', formData).then(function (response) { if(response.type != 'error') { setStatusMsg("toggle-otp-status", "Your account details have been successfully updated.", true); } else { setStatusMsg("toggle-otp-status", "

There was a problem updating your account details.

Error: Unknown

", true); } }) .fail(function() { setStatusMsg("toggle-otp-status", "

There was a problem updating your account details.

Error: Unknown

", true); }) .always(function() { hideMainLoader(); }) }); // OTP PAGE var resendTimer, resendTimerCurrent, resendTimerAmount = 60, otpText = "Send a new code", otpTextTimer = "Send a new code in 60 secs", originalToken, error = { 'error100': "Internal error has occured, please contact support", 'error250': "Token provided is unknown.", 'error251': "Token provided has already been used.", 'error252': "Token provided has been cancelled.", 'error253': "Token provided has expired." } checkToken(); cleanTokens(); $("#resend-otp").on("click", function(event){ event.preventDefault(); if(resendTimerCurrent != undefined) return; $('#error-msg').text(""); var token = $("#otp-form input[name=token]").val(); var payload = { 'token': token // current token to be replaced } callPlatformAPI('auth/2fa-refresh', payload).then(function (response) { if(response.type != "error") { $("#otp-form input[name=token]").val(response.token); // inject new token into token input localStorage.setItem("otp_" + originalToken, response.token); // save to be reloaded if page is refreshed startCountdown(); } else { var errorText = error['error100']; // generic error if(error['error' + response.code]) { // specific response, if we have it errorText = error['error' + response.code]; } $('#error-msg').text(errorText); } }) }) function startCountdown(){ if(resendTimerCurrent != undefined) return; resendTimerCurrent = resendTimerAmount; var resendButton = $('#resend-otp'); resendButton.attr("disabled", 'true'); resendButton.val(otpTextTimer); // preset timer text on button to not wait for 1st tick to change - desktop resendButton.siblings('span').children('span.ui-btn-text').html(otpTextTimer); // preset timer text on button to not wait for 1st tick to change - mobile resendTimer = setInterval(() => { if (resendTimerCurrent > 1) { resendTimerCurrent--; var newTimerText = otpTextTimer.replaceAll(/\d{1,2}/g, resendTimerCurrent); resendButton.val(newTimerText); // replace digits with timer count - desktop resendButton.siblings('span').children('span.ui-btn-text').html(newTimerText); // replace digits with timer count - mobile resendButton.attr("disabled", 'true'); } else { clearInterval(resendTimer); resendButton.val(otpText); // set text to no timer text - desktop resendButton.siblings('span').children('span.ui-btn-text').html(otpText); // set text to no timer text - mobile resendTimerCurrent = undefined; // reset current resendButton.removeAttr("disabled"); } }, 1000); } // if page is refreshed, php post call token will be reloaded, which has since been cancelled on refresh. // load saved refreshed token and insert into token input for use. function checkToken() { originalToken = $("#otp-form input[name=token]").val(); var lsToken = localStorage.getItem("otp_" + originalToken); if(lsToken) { $("#otp-form input[name=token]").val(lsToken); } } // since php handles the login, and does not have access to the localstorage to clear old tokens, // we clear old tokens on load of the otp page. // any otp tokens not associated with token currently being passed by php request is removed function cleanTokens() { var items = { ...localStorage }; var filteredItems = Object.keys(items).filter(item => item.indexOf('otp_') !== -1 && item.indexOf(originalToken) == -1); filteredItems.forEach(function(item) { localStorage.removeItem(item); }) } }); $(function() { var cashierScriptLoaded = false; var eventSet = false; var triggerElement = document.createElement("div") triggerElement.className = "whg-cashier-ui-open"; triggerElement.style.display = "none"; document.body.append(triggerElement); // WITHDRAWALS IN CASHIER console.log("withdrawals in cashier"); var launcher = document.getElementsByTagName("whg-cashier-ui-launcher")[0]; if (typeof(launcher) != 'undefined' && launcher != null) { var config = JSON.parse( launcher.getAttribute("config") ); var withdrawalConfig = { ...config, mode:"withdraw" } var withdrawalTriggerElement = document.createElement("div") withdrawalTriggerElement.className = "whg-cashier-withdrawal-trigger"; withdrawalTriggerElement.style.display = "none"; document.body.append(withdrawalTriggerElement); function buttonClick(e){ e.preventDefault(); e.stopImmediatePropagation(); launcher.setAttribute("config", JSON.stringify(withdrawalConfig) ); if(!cashierScriptLoaded) { $.getScript("https://scontent-wh.whitehatgaming.com/js/whg-cashier-ui-launcher/whg-cashier-ui-launcher.min.js" ,function() { cashierScriptLoaded = true; $('#popupBox').remove(); $('#overlay').hide(); $(withdrawalTriggerElement).trigger('click'); if(!eventSet) { var cashierCloseButton = document.getElementById("cashier-ui-close"); cashierCloseButton.addEventListener("click", function() { launcher.setAttribute("config", JSON.stringify(config)); if (false) { window.postMessage('WHG_BALANCE_REFRESH', '*'); } }); eventSet = true; } }); } else { $(withdrawalTriggerElement).trigger('click'); } } document.body.addEventListener('click', (e) => { const link = e.target.closest('a'); const targetSpan = document.getElementById('withdraw'); if (e.target.matches('a[href="/index.php?page=withdraw"], a[href="index.php?page=withdraw"], a[href*="?page=withdraw"], span#account-withdraw, span#withdraw, a[href*="/withdraw"]' )) { const modalCloseBtn = document.querySelector('#my-account-modal .close'); if (modalCloseBtn) { modalCloseBtn.click(); } buttonClick(e); } else if (e.target instanceof HTMLSpanElement && e.target.parentElement instanceof HTMLAnchorElement && link && link.href.includes('/withdraw')) { buttonClick(e); } else if(e.target.matches('a[href^="/index.php?page=withdraw#"]')){ const modalCloseBtn = document.querySelector('#my-account-modal .close'); if (modalCloseBtn) { modalCloseBtn.click(); } buttonClick(e); } else if (targetSpan && targetSpan.contains(e.target)) { buttonClick(e); } }); } $('body').on('click', 'a[href="/index.php?page=deposit"], a[href="/?page=deposit&gameret=1"], a[href="index.php?page=deposit"], a[href="/deposit"], a[href="/deposit/"], .profile-top-buttons .deposit-btn, .cashier-link', function (e) { e.preventDefault(); e.stopImmediatePropagation(); if(!cashierScriptLoaded){ $.getScript("https://scontent-wh.whitehatgaming.com/js/whg-cashier-ui-launcher/whg-cashier-ui-launcher.min.js", function(data, textStatus, jqxhr) { $('#popupBox').remove(); $('#overlay').hide(); setTimeout(function() { $(triggerElement).trigger('click'); if(!eventSet) { var cashierCloseButton = document.getElementById("cashier-ui-close"); cashierCloseButton.addEventListener("click", function() { if (typeof launcher !== 'undefined' && typeof config !== 'undefined') { launcher.setAttribute("config", JSON.stringify(config)); } if (false) { window.postMessage('WHG_BALANCE_REFRESH', '*'); } }); eventSet = true; } }, 1000); }); cashierScriptLoaded = true; } else { $(triggerElement).trigger('click'); } }); if(window.location.href.search('cashier=1') !== -1 && !window.location.href.includes('/message')) { if (false) { if (!cashierScriptLoaded){ $.getScript("https://scontent-wh.whitehatgaming.com/js/whg-cashier-ui-launcher/whg-cashier-ui-launcher.min.js", function(data, textStatus, jqxhr) { showCashierOnPostmessage(); }); } } else { window.location = "/index.php?page=login&sender=deposit"; } } function showCashierOnPostmessage() { function messageListener(event) { if (event.data == 'cashier-ready') { console.log('post message ready'); $('.whg-cashier-ui-open').trigger('click'); window.removeEventListener('message', messageListener); } } window.addEventListener('message', messageListener, false); console.log('showCashierOnPostmessage'); } }); /** * PhonePrefixSelector - Reusable phone prefix dropdown with caching and search * * @description * Fetches phone prefixes from lookup-service API, caches for 12 hours, * deduplicates by prefix, sorts numerically, and renders to select element. * Optionally supports search filtering and remembers user's last selection. * * @requires LOOKUP_SERVICE_HOST - PHP constant injected via jsutils.php * @requires jQuery * @requires setCookie/getCookie - Global functions from jsutils.php * * @example Basic usage (native select, no search) * const selector = new PhonePrefixSelector({ * selectElement: '#phone_prefix', * defaultCountry: 'GB', * existingPrefix: '44' * }); * * @example With search enabled * // HTML: * // * const selector = new PhonePrefixSelector({ * selectElement: '#phone_prefix', * enableSearch: true, * defaultCountry: 'GB' * }); * * @example Custom cache TTL * const selector = new PhonePrefixSelector({ * selectElement: '#phone_prefix', * cacheTTL: 1440 // Cache for 24 hours instead of default 12 * }); * * @example Get/set values programmatically * const selector = new PhonePrefixSelector({ selectElement: '#phone_prefix' }); * * // Get selected prefix * const prefix = selector.getValue(); // Returns "44" * * // Set prefix programmatically * selector.setValue('1'); // Sets to US +1 * * // Force refresh (flush cache and re-fetch) * selector.refresh(); * * // Cleanup when done * selector.destroy(); * * @param {Object} options Configuration options * @param {string|jQuery} options.selectElement - CSS selector or jQuery element for '; for (i = 0; i <= 23; i++) { selectedHours = (i === minHour || i === realityCheckData.thours) ? ' selected' : ''; message += '' + i + ''; } message += 'Minute(s): Repeat:

'; message += '
Set Reminder
'; // not elegant solution but solves firefox problem. if ($('#my-account-modal').length && $.browser.mozilla) { $('#my-account-modal').modal('hide'); } popup('300','Timer',message,'false','true','set-timer-check-popup'); } function recordTermsAccepted(terms, callback){ $.ajax({ type: "POST", url: "/ajax/ajaxhandler.php", data: { req: 'customrecord', type: 'terms', details: terms }, success: function(data) { console.log(data); if(callback && typeof callback == "function"){ callback(true); } } }); } //Verify submission of phone number function verifySubmitNumber() { //prevent submit being double clicked. $('#phone_submit_btn').prop('disabled',true); var msg = 'A verification code has been sent to your mobile, please proceed to Step 2.'; $.ajax({ type: 'POST', url: '/ajax/ajaxhandler.php', data: { req: 'verify', sender: 'number', country: $("#country").val(), number: $("#number").val() }, dataType: 'json', success: function (jsonRsp) { if(!jsonRsp.status) //failed. msg = jsonRsp.error; $('#verify_step1').html('

'+msg+'

'); } }); return false; } // Disables the withdrawal form function disableBankTransferOnMethod(methodToDisable) { var selectedMethod = $('#method option:selected').val(); var formMustBeDisabled = selectedMethod === methodToDisable; [ 'input[name="details[password]"', 'input[name="details[amount]"', 'input[name="details[params][account]"', 'input[name="details[params][fi]"', 'input[name="details[params][transit]"', 'input[name="details[params][acct]"', 'input[name="details[params][accountType]"', 'input[name="details[params][bank]"', 'input[name="details[params][iban]"', 'input[name="details[params][address]"', 'input[name="details[params][bic]"', 'button[name="submit"', ].forEach(elementKey => { if (formMustBeDisabled) { $(elementKey).attr('disabled','disabled'); } else { $(elementKey).removeAttr('disabled'); } }) } function setStatusMsg(id, message, status){ $('#'+id).html(message); if(status) $('#'+id).addClass('success').removeClass('error'); else $('#'+id).addClass('error').removeClass('success'); } function showMainLoader(){ $('body').append('
'); } function hideMainLoader(){ $(".main-loader").remove(); } var referAFriendReset = function(html){ $('#refer-a-friend-page').html(html); }; // Refer a friend $(document).ready(function(){ $('body').on('submit', '#refer-a-friend', function(e) { e.preventDefault(); formProperties = $('#refer-a-friend').serializeArray(); formProperties.push({ name: 'req', value: 'referafriend' }); $.ajax({ type:'POST', url: '/ajax/ajaxhandler.php', data: formProperties, dataType: 'json' }) .done(function(data) { data.success = data.success == 1; var referAFriendPage = $('#refer-a-friend-page').html(), referAFriendSuccessMessage = '

All done! We have invited your friend!

', referAFriendFailureMessage = '

Internal error has occured, please contact support

', tryAgainOrSendAnother = data.success ? 'Send another' : 'Try again'; $('#refer-a-friend-page').html(data.success ? referAFriendSuccessMessage : referAFriendFailureMessage); $('#refer-a-friend-page').append( $('
').append( $('